﻿using AutoMapper;
using Jinjia.Approve.Entity;
using Jinjia.Approve.IRepository;
using Jinjia.Approve.Model;
using Jinjia.Core.Attribute;
using JinJia.Core.Base.Exceptions;
using Jinjia.Core.BaseInfrastructure.StorageModel;
using Jinjia.Core.BaseInfrastructure.StorageModel.Impl;
using Jinjia.Core.UnitOfWork.UnitOfWorkComponent;
using Microsoft.AspNetCore.Http;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Jinjia.Approve.Entity.Entity;
using Jinjia.Approve.Entity.Entity.JJFlow;
using Jinjia.Approve.Model.Input;
using Jinjia.Approve.Model.VM;
using Jinjia.Approve.Model.VM.JJFlow;

namespace Jinjia.Approve.Repository
{
    public class JJFlowCommentRepository : BaseRepository<jj_flow_comment_tbl>, IJJFlowCommentRepository
    {
        private readonly IMapper _mapper;
        private readonly IHttpContextAccessor _httpContextAccessor;

        public JJFlowCommentRepository(IUnitOfWork unitOfWork, IInitUserInfo initUserInfo
            , IMapper mapper, IHttpContextAccessor httpContextAccessor)
            : base(unitOfWork, initUserInfo)
        {
            _mapper = mapper;
            _httpContextAccessor = httpContextAccessor;
        }

        public async Task<int> Save(jj_flow_comment_tbl data)
        {
            if (data.id <= 0) //新增
            {
                var id = await _db.Insertable(data).ExecuteReturnIdentityAsync();
                return id;
            }
            else
            {
                await _db.Updateable(data)
                    .Where(x => x.id == data.id)
                    .ExecuteCommandAsync();
                return data.id;
            }
        }

        public async Task<List<jj_flow_comment_tbl>> GetCommentByBizOrderIdAndModularKey(string biz_order_id, string modular_key)
        {
            return await _db.Queryable<jj_flow_comment_tbl>()
                .Where(x => x.biz_order_id == biz_order_id && x.modular_key == modular_key && x.deleted == 0).ToListAsync();
        }

        public async Task UpdateIsAppend(List<int> ids, int is_append)
        {
            await _db.Updateable<jj_flow_comment_tbl>()
                .SetColumns(x => new jj_flow_comment_tbl() { is_append = is_append })
                .Where(x => ids.Contains(x.id))
                .ExecuteCommandAsync();
        }

        public async Task UpdateIsAppend(int id, int is_append)
        {
            await UpdateIsAppend(new List<int>() { id }, is_append);
        }


        public Task<List<JJFlowCommentVM>> GetJJFlowCommentsWhitFilter(JJFlowCommentSearchInput input)
        {
            var query = _db.Queryable<jj_flow_comment_tbl, erpa_user_tbl>((x, y) => new JoinQueryInfos(
                    JoinType.Left, x.create_user_id == y.id))
                .Where((x, y) => x.biz_order_id == input.biz_order_id && x.modular_key == input.modular_key && x.deleted == 0)
                .Select((x, y) => new JJFlowCommentVM
                {
                    id = x.id,
                    biz_order_id = x.biz_order_id,
                    modular_key = x.modular_key,
                    comment = x.comment,
                    node_name = x.node_name,
                    node_action = x.node_action,
                    user_name = y.user_name,
                    is_append = x.is_append,
                    update_time = x.update_time
                }).OrderBy(x => x.id, OrderByType.Desc)
                .ToList();
            var result = _mapper.Map<List<JJFlowCommentVM>>(query);
            foreach (var item in result)
            {
                var file_qury = _db.Queryable<erpa_upload_file_tbl>().Where(x => x.external_key == input.modular_key && x.related_no == item.id.ToString() && x.delete_status == 0)
                    .ToList();
                item.files = _mapper.Map<List<FileVM>>(file_qury);
            }

            return Task.FromResult(result);
        }


        private int GetUserId()
        {
            var currentUserId = GetClaim("id");
            var result = int.TryParse(currentUserId, out int userId);
            return result ? userId : -100;
        }

        /// <summary>
        /// 获取授权用户身份信息
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        private string GetClaim(string type)
        {
            return _httpContextAccessor.HttpContext.User.Claims.FirstOrDefault(x => x.Type == type)?.Value;
        }


        [UseTran]
        public async Task<int> InsertCommentAndFileInfo(JJFlowCommentCreateInput input)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(input.comment) && input.files.Count == 0)
                {
                    throw new BusinessException("评论内容或附件不能为空!");
                }

                var biz_order_id_str = input.biz_order_id.ToString();
                var now = DateTime.Now;
                var userId = GetUserId();
                var comment_model = _mapper.Map<jj_flow_comment_tbl>(input);
                comment_model.update_time = now;
                comment_model.create_time = now;
                comment_model.update_user_id = userId;
                comment_model.create_user_id = userId;
                comment_model.deleted = 0;
                comment_model.is_append = string.IsNullOrWhiteSpace(input.comment) == false ? 1 : 0;
                //返回主表自增id
                var id = await _db.Insertable(comment_model).ExecuteReturnIdentityAsync();
                if (id > 0)
                {
                    var file_list = new List<erpa_upload_file_tbl>();
                    if (input.files != null)
                    {
                        foreach (var item in input.files)
                        {
                            var file_model = new erpa_upload_file_tbl();
                            file_model.file_url = item.file_url;
                            file_model.file_name = item.file_name;
                            file_model.file_type = item.file_type;
                            file_model.external_key = input.modular_key;
                            file_model.related_no = id.ToString();
                            file_model.update_time = now;
                            file_model.create_time = now;
                            file_model.update_user_id = userId;
                            file_model.create_user_id = userId;
                            file_model.delete_status = 0;
                            file_list.Add(file_model);
                        }
                    }

                    if (file_list.Count > 0)
                    {
                        _db.Insertable(file_list).ExecuteCommand();
                    }
                }
                else
                {
                    throw new BusinessException("主表id为0");
                }

                //更新评论状态
                await UpdateIsAppend(biz_order_id_str, input.modular_key);
                return id;
            }
            catch (Exception)
            {
                throw new BusinessException("评论失败!");
            }
        }

        public async Task UpdateIsAppend(string biz_order_id, string modular_key)
        {
            //查询所有评论
            var comments = await _db.Queryable<jj_flow_comment_tbl>()
                .Where(x => x.biz_order_id == biz_order_id && x.modular_key == modular_key && x.deleted == 0).ToListAsync();
            //最新的评论
            var lastest_comment = comments.Where(x => string.IsNullOrWhiteSpace(x.comment) == false).OrderByDescending(x => x.id).FirstOrDefault();
            //将所有的评论is_append变更为0;
            foreach (var item in comments)
            {
                item.is_append = 0;
            }

            await _db.Updateable(comments).UpdateColumns(it => new { it.is_append }).ExecuteCommandAsync();
            if (lastest_comment != null)
            {
                lastest_comment.is_append = 1;
                await _db.Updateable(lastest_comment).UpdateColumns(it => new { it.is_append }).ExecuteCommandAsync();
            }
        }
    }
}